import os
from functools import partial
from typing import List, Callable

from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QComboBox, QLineEdit
import sys

from ClientUi.deviceManager.deviceManagerBaseDlg import deviceManagerBaseDlg
from ClientUi.controls.CustomList import CustomList, CustomListItemType, CustomItemBase
from ClientUi.deviceManager.searchSerialPortDlg import searchSerialPortDlg
from ClientUi.deviceManager.dev_config import max_scanner_num
from get_config import config, config_save

'''
class CustomItemComboAndEdit(CustomItemBase):
    __cmb = None
    __edt = None
    __cmbCallbacks = {}
    __txtCallbacks = {}

    def __init__(self):
        super().__init__()

    def _onCreateSubWidgetAndLayout(self):
        v = QVBoxLayout()
        self.__cmb = QComboBox()
        self.__edt = QLineEdit()
        self.__edt.editingFinished.connect(partial(self.__textChanged, 1))
        self.__edt.setVisible(False)
        v.addWidget(self.__cmb)
        v.addWidget(self.__edt)
        return v

    def _onSetSubWidgetText(self, subWidget: int, value):
        if subWidget == 0:
            if isinstance(value, List):
                self.__cmb.disconnect()
                self.__cmb.clear()
                self.__cmb.addItems(value)
                self.__cmb.setCurrentIndex(0)
                self.__cmb.currentIndexChanged.connect(partial(self.__comboBoxChanged, subWidget))
            elif isinstance(value, int):
                if self.__cmb.count() <= value:
                    return
                self.__cmb.setCurrentIndex(value)
            elif isinstance(value, str):
                self.__cmb.setCurrentText(value)
        elif subWidget == 1:
            self.__edt.setText(value)
        else:
            return

    def connectComboBox(self, subWidget: int, callback: Callable[[int, int, int], None]):
        self.__cmbCallbacks[subWidget] = callback

    def connectLineEdit(self, subWidget: int, callback: Callable[[int, int, str], None]):
        self.__txtCallbacks[subWidget] = callback

    def _onSwitch(self, subWidget: int):
        print('you should inherit: _onSwitch')

    def __comboBoxChanged(self, subWidget: int, index: int):
        # print(f"Index changed to: {index}, cell combo:{rowIndex}.{columnIndex}")
        try:
            self.__cmbCallbacks[subWidget](self._row, self._column, index)
        except Exception as e:
            pass

    def __textChanged(self, subWidget: int):
        msg = self.sender().text()
        # print(f"text changed to: {msg}, cell:{rowIndex}.{columnIndex}")
        try:
            self.__txtCallbacks[subWidget](self._row, self._column, msg)
        except Exception as e:
            pass

'''

class scannerSettingDlg(deviceManagerBaseDlg):
    __customItems = []

    def __init__(self):
        super().__init__()
        self.setWindowIcon(QIcon(f'{self._clientUiPath}\\images\\icon.ico'))  # 设置窗口图标
        self.setWindowTitle('扫码枪管理')
        scannerList = self._getDevList()
        # 表格中控件绑定事件
        if scannerList is not None:
            scannerList.connectComboBox(1, self.__changeScannerType)
            scannerList.connectButton(2, self.__clickSearchDev)
            scannerList.connectLineEdit(3, self.__changeDevIpOrSerial)
            scannerList.connectLineEdit(4, self.__changeDevPortOrBaud)
            scannerList.connectLineEdit(5, self.__changeDevName)
            scannerList.connectButton(6, self.__clickClearInfo)

    def _onInitTopWidget(self):
        self._createTopWidget('扫码枪数量：', max_scanner_num, config.get('used_scanner_num', 0), True)

    def _onInitDevListHeader(self, devList: CustomList):
        devList.SetColumnTitleAndTypes((('序号', CustomListItemType.LABEL),
                                        ('类型', CustomListItemType.COMBOBOX),
                                        ('搜索', CustomListItemType.BUTTON),
                                        ('IP/串口', CustomListItemType.EDIT),
                                        ('端口/波特率', CustomListItemType.EDIT),
                                        ('备注', CustomListItemType.EDIT),
                                        ('清除', CustomListItemType.BUTTON)))
        devList.SetEditMaxLen(3, 15)
        devList.SetEditMaxLen(4, 6)
        devList.SetEditMaxLen(5, 10)

    def _onInitDevListRows(self, rowCount: int, devList: CustomList):
        devList.setRowCount(rowCount)
        for i in range(rowCount):
            scanner_type = config.get(f"scanner{i + 1}_type", 0)
            if scanner_type == 0:
                # 网络
                devList.setRow(i, (f'{i + 1}', (('网络', '串口'), '网络'), '搜索',
                                    config.get(f"scanner{i + 1}_ipaddress", ''), config.get(f"scanner{i + 1}_port", ''),
                                    config.get(f'scanner{i + 1}_name', ''),
                                    {'icon': f'{self._clientUiPath}\\images\\reset.png'}))
            elif scanner_type == 1:
                # 串口
                devList.setRow(i, (f'{i + 1}', (('网络', '串口'), '串口'), '搜索',
                                   config.get(f"scanner{i + 1}_serialport_num"), config.get(f"scanner{i + 1}_baudrate", ''),
                                   config.get(f'scanner{i + 1}_name', ''),
                                   {'icon': f'{self._clientUiPath}\\images\\reset.png'}))
            #self.__changeScannerType(i, 2, scanner_type)  # qt 的bug，界面未显示前，设置table中的按钮为隐藏功能无效
        self.__delayRun()

    def _onSave(self):
        config['used_scanner_num'] = self._getCurrentDevNum()
        for i in range(config['used_scanner_num']):
            result = self.__getRowInfo(i)
            print(result)
            config[f"scanner{i + 1}_type"] = result[1]
            if result[1] == 0:
                # 网络
                config[f"scanner{i + 1}_ipaddress"] = result[3]
                config[f"scanner{i + 1}_port"] = result[4]
                config[f"scanner{i + 1}_serialport_num"] = ''
                config[f"scanner{i + 1}_baudrate"] = ''
            else:
                # 串口
                config[f"scanner{i + 1}_serialport_num"] = result[3]
                config[f"scanner{i + 1}_baudrate"] = result[4]
                config[f"scanner{i + 1}_ipaddress"] = ''
                config[f"scanner{i + 1}_port"] = ''
            config[f"scanner{i + 1}_name"] = result[5]

        config_save()
        self.accept()

    def __getRowInfo(self, rowIndex: int):
        return self._getDevList().getRow(rowIndex)

    def __clickSearchDev(self, row: int, column: int):
        print(f'__clickSearchDev: {row} {column}')
        wd = searchSerialPortDlg(row)
        def onSearchedSerialPort(row, serialPort):
            self._getDevList().setCell(row, 3, serialPort)
        wd.connect(onSearchedSerialPort)
        wd.exec_()

    def __clickClearInfo(self, row: int, column: int):
        print(f'__clickClearInfo: {row} {column}')
        self._getDevList().clearRow(row, [CustomListItemType.EDIT, CustomListItemType.COMBOBOX])

    def __changeScannerType(self, row: int, column: int, index: int):
        print(f'__changeScannerType: {row} {column}, {index}')
        if index == 0:
            # 网络
            self._getDevList().setCellVisible(row, 2, False)
            self._getDevList().setCell(row, 3, config.get(f"scanner{row + 1}_ipaddress", ''))
            self._getDevList().setCell(row, 4, config.get(f"scanner{row + 1}_port", ''))
        else:
            # 串口
            self._getDevList().setCellVisible(row, 2, True)
            self._getDevList().setCell(row, 3, config.get(f"scanner{row + 1}_serialport_num", ''))
            self._getDevList().setCell(row, 4, config.get(f"scanner{row + 1}_baudrate", ''))

    def __changeDevIpOrSerial(self, row: int, column: int, ip: str):
        print(f'__changeDevIpOrSerial: {row} {column}, {ip}')

    def __changeDevPortOrBaud(self, row: int, column: int, name: str):
        print(f'__changeDevPortOrBaud: {row} {column}, {name}')

    def __changeDevName(self, row: int, column: int, name: str):
        print(f'__changeDevName: {row} {column}, {name}')

    def __hideSearchBtnEvent(self):
        rowCount = self._getDevList().rowCount()
        for i in range(rowCount):
            self.__changeScannerType(i, 2, config.get(f"scanner{i + 1}_type", 0))

    def __delayRun(self):
        self.__hideSearchBtnTimer = QTimer()
        self.__hideSearchBtnTimer.setSingleShot(True)
        self.__hideSearchBtnTimer.timeout.connect(self.__hideSearchBtnEvent)
        self.__hideSearchBtnTimer.start(1)

    # def showEvent(self, ev):
    #     super().showEvent(ev)

def test_scannerSettingDlg():
    app = QApplication(sys.argv)
    current_path = os.path.abspath(__file__)
    path = os.path.dirname(current_path)
    path = os.path.dirname(path)
    app.setStyleSheet(open(f'{path}/styleSheet.qss', encoding='utf-8').read())
    window = scannerSettingDlg()
    window.showNormal()
    sys.exit(app.exec_())

if __name__ == '__main__':
    test_scannerSettingDlg()